package nz.co.listit.hailacabprototype;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.telephony.TelephonyManager;
import android.util.Log;

public abstract class ListItResClient extends Activity implements Runnable {
	private PowerManager.WakeLock _wakeLock;

	protected ProgressDialog _progDlg;
	protected Boolean _debug = false;
	protected static final String PREFERENCE = "nz.co.listit.TaxiValet";
	protected static final String TAG = "LIST-IT EVENT";
	protected static final String FMT_ERROR = "%s - JSON key does not exists: %s";

	public static final String KEY_SERVER_MESSAGE = "message";
	public static final String KEY_SERVER_MESSAGE_INNER = "message_inner";
	public static final String KEY_SERVER_RET_CODE = "return_code";
	public static final String KEY_SERVER_C2DM_EMAIL = "c2dm_email";
	public static final String KEY_SERVER_PICKUP = "pickup";
	public static final String KEY_SERVER_DESTINATION = "destination";
	public static final String KEY_SERVER_TEL_NO = "telno";
	public static final String KEY_SERVER_MOBILE = "mobile";
	public static final String KEY_SERVER_SPECIAL_INSTRUCTION = "info";
	public static final String KEY_SERVER_MOBILE_NUMBER = "mobile";
	public static final String KEY_SERVER_DEBUG_TAXI = "debug";
	public static final String KEY_SERVER_CUSTOMER = "customer";

	public static String SHARED_PREF_LISTIT = "nz.co.listit.TaxiValet.SharedPreferences";

	protected void showError(String title, String error) {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setMessage(error).setTitle(title)

		.setCancelable(false)

		.setPositiveButton("OK", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int d) {
				dialog.cancel();
			}
		});

		AlertDialog alert = builder.create();
		alert.show();
	}

	// called on OK
	protected void onOKResult(JSONObject json) {
		// do nothing
	}

	// called on INVALID_USERNAME
	protected void onInvalidUsername(JSONObject json) {
		// do nothing
	}

	// called on INVALID_PASSWORD
	protected void onInvalidPassword(JSONObject json) {
		// do nothing
	}

	// called on UNREGISTERED_DEVICE
	protected void onUnRegisteredDevice(JSONObject json) {
		// do nothing
	}

	// called on DEVICE_NOT_LOGGED_IN
	protected void onDeviceNotLoggedIn(JSONObject json) {
		// do nothing
	}

	// called on LOGGED_IN
	protected void onLoggedIn(JSONObject json) {
		// do nothing
	}

	// called on LOGGED_OUT
	protected void onLoggedOut(JSONObject json) {
		// do nothing
	}

	// called on STATUS_BUSY
	protected void onStatusBusy(JSONObject json) {

	}

	// called on STATUS_AVAILABLE
	protected void onStatusAvailable(JSONObject json) {

	}

	// called on CONNECTION_ERROR
	protected void onConnectionError(JSONObject json) {
		if (_progDlg != null)
			_progDlg.dismiss();

		try {
			this.showError("List-It server error",
					json.getString(KEY_SERVER_MESSAGE));
		} catch (JSONException e) {
			Log.e(TAG, String.format(FMT_ERROR, "onServerError",
					KEY_SERVER_MESSAGE));
		}
	}

	// called on UNKNOWN_ERROR
	protected void onUnknownError(JSONObject json) {
		if (_progDlg != null)
			_progDlg.dismiss();
		
		this.showError("List-It unknown error",
				"Unknown error.  Please contact List-It");
	}

	// called on SERVER_ERROR
	protected void onServerError(JSONObject json) {
		if (_progDlg != null)
			_progDlg.dismiss();

		try {
			this.showError("List-It server error",
					json.getString(KEY_SERVER_MESSAGE));
		} catch (JSONException e) {
			Log.e(TAG, String.format(FMT_ERROR, "onServerError",
					KEY_SERVER_MESSAGE));
		}
	}

	// called on JOB_TERMINATE
	protected void onJobTerminate(JSONObject json) {
		// do nothing
	}

	// called on JOB_WITHDRAW
	protected void onJobWithdraw(JSONObject json) {
		// do nothing
	}

	// called on JOB_COMPLETE
	protected void onJobComplete(JSONObject json) {
		// do nothing
	}

	// called on HAS_JOB
	protected void hasJob(JSONObject json) {
		// do nothing
	}

	protected Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			JSONObject json = (JSONObject) msg.obj;

			switch (WEBSERVER_MESSAGES.values()[msg.what]) {
			case OK:
				onOKResult(json);
				break;

			case INVALID_USERNAME:
				onInvalidUsername(json);
				break;

			case INVALID_PASSWORD:
				onInvalidPassword(json);
				break;

			case UNREGISTERED_DEVICE:
				onUnRegisteredDevice(json);
				break;

			case DEVICE_NOT_LOGGED_IN:
				onDeviceNotLoggedIn(json);
				break;

			case LOGGED_IN:
				onLoggedIn(json);
				break;

			case LOGGED_OUT:
				onLoggedOut(json);
				break;

			case STATUS_BUSY:
				onStatusBusy(json);
				break;

			case STATUS_AVAILABLE:
				onStatusAvailable(json);
				break;

			case CONNECTION_ERROR:
				onConnectionError(json);
				break;

			case UNKNOWN_ERROR:
				onUnknownError(json);
				break;

			case SERVER_ERROR:
				onServerError(json);
				break;

			case JOB_TERMINATE:
				onJobTerminate(json);
				break;

			case JOB_WITHDRAW:
				onJobWithdraw(json);
				break;

			case JOB_COMPLETE:
				onJobComplete(json);
				break;

			case HAS_JOB:
				hasJob(json);

			default:
				break;
			}
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);

		_wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK,
				"DoNotDimScreen");
	}

	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();

		_wakeLock.release();
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();

		_wakeLock.acquire();
	}

	public abstract void run(); // Implements Runable Interface

	public String getDeviceID() {
		final TelephonyManager tm = (TelephonyManager) getBaseContext()
				.getSystemService(Context.TELEPHONY_SERVICE);

		// final String tmDevice, tmSerial, androidId;
		return tm.getDeviceId(); // IMEI

		/*
		 * tmDevice = "" + tm.getDeviceId(); tmSerial = "" +
		 * tm.getSimSerialNumber(); androidId = "" +
		 * android.provider.Settings.Secure.getString( getContentResolver(),
		 * android.provider.Settings.Secure.ANDROID_ID);
		 * 
		 * UUID deviceUuid = new UUID(androidId.hashCode(), ((long)
		 * tmDevice.hashCode() << 32) | tmSerial.hashCode()); String result =
		 * deviceUuid.toString(); return result;
		 */
	}
	
	public String getLocalIpAddress() {
	    try {
	        for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
	            NetworkInterface intf = en.nextElement();
	            for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
	                InetAddress inetAddress = enumIpAddr.nextElement();
	                if (!inetAddress.isLoopbackAddress()) {
	                    return inetAddress.getHostAddress().toString();
	                }
	            }
	        }
	    } catch (SocketException ex) {
	        Log.e("error", ex.toString());
	    }
	    return null;
	}
}
